Android — 自定义View(四)之绘制图片文字

前言

回顾一下上一篇的内容,主要介绍了画布的几种操作:位移(translate)、缩放(scale)、旋转(rotate)、错切(skew),还有画布的保存(save)和回滚(restore)等等。知道这些方法参数的含义以及方法实现的效果就行了。而这篇文章主要是介绍怎样绘制图片文字,这篇文章过后,基本上大部分的自定义View都能实现了,想想是不是很刺激?当然,这也不是终点,后面还有更加酷炫的效果。先来看看本节的目录:

  1. 绘制图片
    • drawPicture(矢量图)
      • 使用Picture提供的draw方法绘制
      • 使用Canvas提供的drawPicture方法绘制
      • 将Picture包装成PictureDrawable,使用PictureDrawable的draw方法绘制
    • drawBitmap(位图)
  2. 绘制文字
    • drawText()
    • drawPosText()
    • drawTextOnPath()

其实我感觉绘制图片用的比较少,绘制文字还是很重要的,可以直接跳到绘制文字部分看,当然,适当了解一下绘制图片还是很有必要的,毕竟学这些东西只是脑子里有一个印象,到用着的时候也知道看什么,不是吗?那就开始今天的讲解了。

绘制图片

绘制图片有两种方式,即drawPicture(矢量图)、和drawBitmap(位图)。

  • drawPicture

    使用Picture前请关闭硬件加速,以免引起不必要的问题。

    在AndroidMenifest文件中application节点下添加android:hardwareAccelerated=”false”以关闭整个应用的硬件加速。

    我们可以把Picture看做一个录制Canvas操作的录像机。

    相关API:

    | 相关方法 | 简介 |
    | —————————————- | —————————————- |
    | public int getWidth() | 获取宽度 |
    | public int getHeight() | 获取高度 |
    | public Canvas beginRecording(int width,int height) | 开始录制(返回一个Canvas,在Canvas中所有的绘制都会存储在Picture中) |
    | public void endRecording() | 结束录制 |
    | public void draw(Canvas canvas) | 将Picture中内容绘制到Canvas中 |

    beginRecording()和endRecording()是成对出现的,开始录制和结束录制之间的操作会记录在Picture中。

    录制内容:

    1
    2
    3
    4
    5
    6
    7
    8
    public void recording() {
    mPicture = new Picture();
    //开始录制
    Canvas canvas = mPicture.beginRecording(mWidth, mHeight);
    canvas.drawCircle(0, 0, 100, mPaint);
    //结束录制
    mPicture.endRecording();
    }

    录制内容只是将一些Canvas操作用Picture保存起来,录制内容并不会显示在屏幕上。那怎么样要才能显示出来呢?你肯定会说:那还用你说?肯定用上面Picture提供的draw方法绘制出来呀。

    emmmm,说的有道理,但是我们想要把Picture中录制的操作绘制出来的话,有三种方法:

    • 使用Picture提供的draw方法绘制
    • 使用Canvas提供的drawPicture方法绘制
    • 将Pictur包装成PictureDrawable,使用PictureDrawable的draw方法绘制

    但是第一种方法对Canvas有影响,我们一般不使用,第三种方法有太繁琐,我建议使用第二种方法。

    绘制内容:

    1
    2
    3
    4
    5
    6
    7
    @Override
    protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.translate(mWidth / 2, mHeight / 2);
    recording();
    canvas.drawPicture(mPicture);
    }

    实际上,recording()方法也可以放在构造方法中,只要是在绘制内容之前调用就行。

  • drawBitmap

    获取Bitmap就不多说了,四种方法。关于绘制Bitmap有三种方法,如下:

    1
    2
    3
    4
    5
    6
    7
    // 第一种
    public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint)
    // 第二种
    public void drawBitmap (Bitmap bitmap, float left, float top, Paint paint)
    // 第三种
    public void drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint)
    public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint)

    第一种方法中的Matrix参数是用来在绘制的时候对图片进行变换,如果只是将图片的内容绘制出来的话直接new Matrix()实例化一个就行了。关于Matrix后面会详解的。

    第二种方法中间两个参数则是指定了图片左上角的坐标。

    第三种方法就比较逗了,中间两个参数分别制定了两个矩形,第一个矩形指定绘制图片的区域,第二个矩形指定图片在屏幕上显示(绘制)的局域。

绘制文字

绘制文字有三类方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 第一类
public void drawText (String text, float x, float y, Paint paint)
public void drawText (String text, int start, int end, float x, float y, Paint paint)
public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)
public void drawText (char[] text, int index, int count, float x, float y, Paint paint)
// 第二类
public void drawPosText (String text, float[] pos, Paint paint)
public void drawPosText (char[] text, int index, int count, float[] pos, Paint paint)
// 第三类
public void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint)
public void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)

第一类:指定文本基线开始绘制(基线X默认在字符串左侧,基线Y默认在字符串下方)

1
2
3
4
String text = "Omooo";
canvas.drawText(text, 0, 0, mPaint);
//文本、开始截取位置、结束截取位置、基线X、基线Y、画笔
canvas.drawText(text, 0, 4, 0, 100, mPaint);

在截取字符串的时候是前闭后开

第二类:分别指定每个文字的位置

这一类不怎么常用,毕竟要指定每个字符的坐标值,过于繁琐。

第三类:指定一个路径,根据路径绘制文字

这个就比较厉害了,用到了Path,emmmm,下一篇再讲。

我们一直都向往,面朝大海,春暖花开。 但是几人能做到,心中有爱,四季不败?